/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package worms;

import gameengine.GameContainer;
import java.awt.event.*;
import network.*;
import network.messages.*;
import java.awt.*;

/**
 * Classe que representa o jogador que está jogando nessa máquina (implementação singleton)
 * @author Victor
 */
public class PlayerAtual extends Player
{

	private static final String PREFIXO_PLAYER_ATUAL = "p1";
	private Cliente cliente;
	private GameContainer container;

	protected PlayerAtual(int id, Point posicao, Cliente cliente, GameContainer container)
	{
		super(id, posicao, PREFIXO_PLAYER_ATUAL, container);
		this.cliente = cliente;
		this.container = container;
	}

	/**
	 * Cria o jogador atual, caso ele não esteja criado!
	 * @owner Victor
	 */
	public static PlayerAtual Create(int id, Point posicao, Cliente cliente, GameContainer container)
	{
		PlayerAtual novaInstancia = new PlayerAtual(id, posicao, cliente, container);
		novaInstancia.SetEstadoJogador(ESTADO_PARADO);

		return novaInstancia;
	}

	@Override
	public void SetEstadoJogador(int estado)
	{
		super.SetEstadoJogador(estado);

		MensagemChangeEstado changeEstado = new MensagemChangeEstado();
		changeEstado.SetId(GetId());
		changeEstado.SetEstadoMovimentacao(GetEstadoJogador());
		changeEstado.SetEstadoAngulacao(GetDirecaoAtual());
		changeEstado.SetVelocidadeY((double) GetVelocidadeY());
		cliente.SendContent(changeEstado.GetJSONString());
	}

	@Override
	public void SetDirecaoAtual(int direcao)
	{
		super.SetDirecaoAtual(direcao);

		MensagemChangeEstado changeEstado = new MensagemChangeEstado();
		changeEstado.SetId(GetId());
		changeEstado.SetEstadoMovimentacao(GetEstadoJogador());
		changeEstado.SetEstadoAngulacao(GetDirecaoAtual());
		changeEstado.SetVelocidadeY((double) GetVelocidadeY());
		cliente.SendContent(changeEstado.GetJSONString());
	}

	public void PularMensagem()
	{
		Pular();

		MensagemChangeEstado changeEstado = new MensagemChangeEstado();
		changeEstado.SetId(GetId());
		changeEstado.SetEstadoMovimentacao(GetEstadoJogador());
		changeEstado.SetEstadoAngulacao(GetDirecaoAtual());
		changeEstado.SetVelocidadeY((double) GetVelocidadeY());
		cliente.SendContent(changeEstado.GetJSONString());
	}

	/**
	 * Controla o jogador
	 * @owner Victor
	 */
	public void TestarInput(int keyCode)
	{
		if (!IsMorto())
		{
			if (keyCode == KeyEvent.VK_D)
			{
				SetEstadoJogador(ESTADO_ANDANDO_FRENTE);
			} else if (keyCode == KeyEvent.VK_A)
			{
				SetEstadoJogador(ESTADO_ANDANDO_TRAS);
			} else if (keyCode == KeyEvent.VK_UP)
			{
				AlterarAngulacao(1);
			} else if (keyCode == KeyEvent.VK_DOWN)
			{
				AlterarAngulacao(-1);
			} else if (keyCode == KeyEvent.VK_SPACE)
			{
				Atirar();
			} else if (keyCode == KeyEvent.VK_W)
			{
				PularMensagem();
			}

		}
	}

	/**
	 * Disparado quando uma tecla do teclado é solta
	 * @owner Victor
	 */
	public void OnTeclaSolta(int keyCode)
	{
		if (!IsMorto())
		{
			if (keyCode == KeyEvent.VK_D || keyCode == KeyEvent.VK_A)
			{
				SetEstadoJogador(ESTADO_PARADO);
			}
		}
	}

	/**
	 * Disparado quando o mouse é movido
	 * @owner Victor
	 */
	public void OnMouseMove(MouseEvent e)
	{
	}

	/**
	 * Disparado quando algum botão do mouse é clicado
	 * @owner Victor
	 */
	public void OnMouseDown(MouseEvent e)
	{
	}

	/**
	 * Envia a posicao do jogador para os outros clientes
	 * @owner Victor
	 */
	public void ReportarPosicaoJogador()
	{
		MensagemUpdatePosicaoPlayer updatePosicaoPlayer = new MensagemUpdatePosicaoPlayer();
		updatePosicaoPlayer.SetFrom(cliente.GetId());
		updatePosicaoPlayer.SetPosicaoX(this.GetPosicao().x);
		updatePosicaoPlayer.SetPosicaoY(this.GetPosicao().y);
		updatePosicaoPlayer.SetVelocidadeY((double) this.GetVelocidadeY());
		cliente.SendContent(updatePosicaoPlayer.GetJSONString());
	}

	/**
	 * Cria um tiro
	 * @owner Victor
	 */
	public void Atirar()
	{
		Point posicaoTiro = new Point(GetPosicao().x + 100 * GetLado() * -1, GetPosicao().y + OFFSETS_Y[GetDirecaoAtual()]);
		Tiro tiro = new Tiro(posicaoTiro, GetAngulo(), GetId(), container);
		container.AddSprite(tiro);

		cliente.SendContent(tiro.GetMensagemTiro().GetJSONString());
	}

	/**
	 * Aumenta ou dininui a angulação da arma, segund o modificador passado
	 * @owner Victor
	 */
	public void AlterarAngulacao(int modificador)
	{
		int novoValor = GetDirecaoAtual() + modificador;
		if (novoValor < 0)
		{
			novoValor = 0;
		} else if (novoValor >= Player.DIRECOES.length)
		{
			novoValor = Player.DIRECOES.length - 1;
		}

		SetDirecaoAtual(novoValor);
	}
}
